using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading;
using System.Windows.Forms;

using PowerPoint = Microsoft.Office.Interop.PowerPoint;
using Graph = Microsoft.Office.Interop.Graph;
using System.Runtime.InteropServices;

using Outcoding.GraphGenerator.Entities;
using Outcoding.GraphGenerator.Composition;
using Outcoding.GraphGenerator.Util.Logging;
using Outcoding.GraphGenerator.Generator;

namespace Outcoding.GraphGenerator.Office2003.UI.WinApplication {
    public partial class FrmChartGenerator : Form {

        #region Private Classes

        private class ListViewObserver : IChartGeneratorObserver {
            private ListView mView;

            public ListViewObserver(ListView view) {
                this.mView = view;
                this.mView.Items.Clear();
            }

            public void OnPresentationParsed(object obj, PresentationParsedEventArgs args){
                string message = string.Empty;
                int imageIndex;
                if (args.TotalSlides > 0){
                    message = string.Format("Presentation successfully parsed. Industry Name: {0} - Total Slides: {1}.",
                        args.IndustryName, args.TotalSlides);
                    imageIndex = 0;
                }
                else
                {
                    message = "Presentation could not be parsed.";
                    imageIndex = 1;
                }

                lock (mView)
                {
                    ListViewItem item = new ListViewItem(message, imageIndex);
                    mView.Items.Add(item);
                }
            }

            public void OnSlideComposing(object sender, SlideComposingEventArgs args)
            {
                string message = string.Format("Composing Slide {0} of {1}.", args.CurrentSlideIndex, args.TotalSlides);
                int imageIndex = 2;

                lock (mView)
                {
                    ListViewItem item = new ListViewItem(message, imageIndex);
                    mView.Items.Add(item);
                }
            }

            public void OnSlideComposed(object sender, SlideComposedEventArgs args)
            {
                string message = string.Empty;
                int imageIndex;

                if (args.IsComposeSuccessful)
                {
                    message = "Slide succesfully composed.";
                    imageIndex = -1;
                }
                else {
                    message = "Slide could not be composed, check error log for further details.";
                    imageIndex = 1;
                }

                lock (mView)
                {
                    ListViewItem item = new ListViewItem(message, imageIndex);
                    mView.Items.Add(item);
                }
            }
        }

        private class ChartGeneratorObserver : IChartGeneratorObserver {

            private RichTextBox mTextBox;

            public ChartGeneratorObserver(RichTextBox textBox) {
                this.mTextBox = textBox;
                mTextBox.Clear();
            }

            public void OnPresentationParsed(object obj, PresentationParsedEventArgs args) {
                string message = string.Empty;
                if(args.TotalSlides > 0){
                    message = string.Format("Presentation successfully parsed. Industry Name: {0} - Total Slides: {1}.\n", 
                        args.IndustryName, args.TotalSlides);
                     
                }else{
                    message = "Presentation could not be parsed.";
                }

                lock (mTextBox) {
                    mTextBox.AppendText(message);   
                }   
            }

            public void OnSlideComposing(object sender, SlideComposingEventArgs args) {
                string message = string.Format("Composing Slide {0} of {1}.", args.CurrentSlideIndex, args.TotalSlides);

                lock (mTextBox) {
                    mTextBox.AppendText(message);
                }   
            }

            public void OnSlideComposed(object sender, SlideComposedEventArgs args) {
                string message = string.Empty;
                if (args.IsComposeSuccessful)
                    message = " (Success).\n";
                else
                    message = " (Failure).\n";

                lock (mTextBox) {
                    mTextBox.AppendText(message);   
                }   
            }
        }

        #endregion

        private string mPath = string.Empty;
        //private ChartGeneratorObserver myObserver;
        private ListViewObserver myObserver;

        public FrmChartGenerator() {
            InitializeComponent();
            myObserver = new ListViewObserver(this.lstvLog);
        }

        public FrmChartGenerator(string[] args) {
            InitializeComponent();
            myObserver = new ListViewObserver(this.lstvLog);
            if (args != null) {
                for (int i = 0; i < args.Length; i++) {
                    if (args[i].CompareTo("-s") == 0) {
                        if (args[i+1] != null) {
                            mPath = args[i + 1];
                            raiseImportThread(mPath);
                        }
                    }
                }
            }
        }

        private void button1_Click(object sender, EventArgs e) {

        }

        private void OnPresentationCreating() {
            lstvLog.Items.Add("Creating Presentation...", -1);
        }

        private void ImportChart() {
            lblStatus.Text = "Importing...";
            ChartGeneratorManager chartManager = new ChartGeneratorManager(mPath);
            chartManager.AddObserver(this.myObserver);

            try {
                chartManager.CreatePresentation();
                lblStatus.Text = "Ready.";
                this.SetTopLevel(true);
                lock (this.lstvLog)
                {
                    lstvLog.Items.Add("Import process finished", 3);
                    lstvLog.Items.Add(string.Empty, -1);
                }
            }catch(Exception exc)   {
                LogManager.Instance.LogError("Error creating presentation", exc);
                MessageBox.Show("Error creating presentation. A log error entry has been created.");
                lblStatus.Text = "Import process failed.";
                lock (this.lstvLog)
                {
                    lstvLog.Items.Add("Import process finished", 1);
                    lstvLog.Items.Add(string.Empty, -1);
                }
            }
        }

        private void raiseImportThread(string path) {
            mPath = path;
            try{
                CheckForIllegalCrossThreadCalls = false;
                Thread thImport = new Thread(new ThreadStart(ImportChart));
                thImport.Start();
                //thImport.Join();
            }catch (ThreadStartException tstartExc){
                LogManager.Instance.LogError("Error creating presentation", tstartExc);
                MessageBox.Show("Error creating presentation. A log error entry has been created.");
            } catch (Exception exc) {
                LogManager.Instance.LogError("Error creating presentation", exc);
                MessageBox.Show("Error creating presentation. A log error entry has been created.");
            }
        }

        private void exitToolStripMenuItem1_Click(object sender, EventArgs e) {
            Application.Exit();
        }

        private void toolStripButton1_Click(object sender, EventArgs e){
            //lblStatus.Text = "Starting import process...";
            string path = System.Configuration.ConfigurationSettings.AppSettings["DataSourcePath"];
            string template = System.Configuration.ConfigurationSettings.AppSettings["TemplatePath"];
            ;
            if (System.IO.File.Exists(template) && !String.IsNullOrEmpty(template)){
                if (!System.IO.File.Exists(path)){
                    OpenFileDialog openDialog = new OpenFileDialog();
                    openDialog.DefaultExt = "*.xml";
                    openDialog.Filter = "Chart Source Files|*.xml";
                    if (openDialog.ShowDialog() == DialogResult.OK)
                        path = openDialog.FileName;
                    else
                        path = null;
                }
                if (!string.IsNullOrEmpty(path)){
                    mPath = path;
                    //ImportChart();
                    raiseImportThread(path);
                    //lblStatus.Text = "Import process finished";
                }
            }
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e) {
            //lblStatus.Text = "Starting import process...";
            string path = System.Configuration.ConfigurationSettings.AppSettings["DataSourcePath"];
            if (!System.IO.File.Exists(path)) {
                OpenFileDialog openDialog = new OpenFileDialog();
                openDialog.DefaultExt = "*.xml";
                openDialog.Filter = "Chart Source Files|*.xml";
                if (openDialog.ShowDialog() == DialogResult.OK)
                    path = openDialog.FileName;
                else
                    path = null;
            }
            if (!string.IsNullOrEmpty(path)) {
                raiseImportThread(path);
                //lblStatus.Text = "Import process finished";
            } 
        }

        private void openToolStripButton_Click(object sender, EventArgs e) {
            OpenFileDialog openDialog = new OpenFileDialog();
            openDialog.DefaultExt = "*.xml";
            openDialog.Filter = "Chart Source Files|*.xml";
            if (openDialog.ShowDialog() == DialogResult.OK) {
                string path = openDialog.FileName;
                //lblStatus.Text = "Starting import process...";
                raiseImportThread(path);
                //lblStatus.Text = "Import process finished";
            }
        }

        private void openToolStripMenuItem1_Click(object sender, EventArgs e) {
            OpenFileDialog openDialog = new OpenFileDialog();
            openDialog.DefaultExt = "*.xml";
            openDialog.Filter = "Chart Source Files|*.xml";
            if (openDialog.ShowDialog() == DialogResult.OK) {
                string path = openDialog.FileName;
                //lblStatus.Text = "Starting import process...";
                raiseImportThread(path);
                //lblStatus.Text = "Import process finished";
            }
        }

        private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
    }
}
